﻿#include "VAOneXMLAdaptorPhysicalPropertyRibbed.h"

#include "Tools/Win64/rapidxml/rapidxml.hpp"
#include "FITKAcousticsPhysics/FITKPhyscisPropertyRibbed.h"
#include "FITKAcousticsPhysics/FITKPhyscisPropertyRibInfo.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractMaterial.h"
#include "FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include "VAOneXMLAdaptorPhysicalPropertyRibInfo.h"

#include <QDebug>

namespace IO
{

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::adaptR()
    {
        return readRibbed();
    }

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::adaptW()
    {
        return writeRibbed();
    }

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::readRibbed()
    {
        if(!_node)
        {
            return false;
        }

        //转换类型为梁
        Acoustics::FITKPhyscisPropertyRibbed* ribbed = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_dataObj);

        if(!ribbed)
        {
            return false;
        }

        bool b = true;
        //获取名称节点
        auto nameNode = _node->first_node("Name");

        if (nameNode == nullptr)
        {
            //材料数据中 名称为必要项 不可为空 并抛出异常日志
            consoleMessage(2, "PhysicalPropertyBeam name is null");
            return false;
        }

        QString strName = readStrNodeValue(nameNode, &b);

        if(b)
        {
            ribbed->setDataObjectName(strName);//名称可以为空，但是节点不能为空
        }

        double SpacingStandardDeviationFractionX = readDoubleAttribute(_node, "SpacingStandardDeviationFractionX", &b);
        double SpacingStandardDeviationFractionY = readDoubleAttribute(_node, "SpacingStandardDeviationFractionY", &b);
        QString dValue = readStrAttribute(_node, "NonribbedPlatePropertyRef", &b);

        if(b)
        {
            ribbed->setSkinPropID(getPhyscisPropertyObjectIdByName(dValue));
        }

        //获取数据属性
        double baseValue = readDoubleAttribute(_node, "base_angle", &b);

        if(b)
        {
            ribbed->setBaseAngle(baseValue);
        }

        //获取备注
        auto noteNode = _node->first_node("Note");

        if (noteNode != nullptr)
        {
            QString strNote = readStrNodeValue(noteNode, &b);
            if(b)
            {
                ribbed->setDescribe(strNote);
            }
        }

        //获取颜色节点
        auto colorNode = _node->first_node("Color");
        float colorR = 0; float colorG = 0; float colorB = 0;
        //根据节点获取颜色
        readColorNodeValue(colorNode, colorR, colorG, colorB);
        //设置颜色
        ribbed->setColor(colorR, colorG, colorB);

        //读取加筋板单向加筋信息
        readRibInfo(SpacingStandardDeviationFractionX,SpacingStandardDeviationFractionY);
        return true;
    }

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::writeRibbed()
    {
        if (!_node)// 判断节点是否存在
        {
            return false;
        }

        //转换类型
        Acoustics::FITKPhyscisPropertyRibbed* data = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_dataObj);

        if(!data)
        {
            return false;
        }

        if(!_node)
        {
            return false;
        }
        // 创建名称节点
        createNodeElement(_node, "Name", data->getDataObjectName());
        // 创建备注节点
        createNodeElement(_node, "Note", data->getDescribe());

        //创建颜色节点
        auto colorNode = createNodeElement(_node, "Color");

        //写入颜色节点信息
        if(colorNode)
        {
            float rgb[3] = { 0.1f, 0.3f, 0.4f };
            //static_cast<float>(0.1),
            //static_cast<float>(0.3),
            //static_cast<float>(0.4) };
            data->getColor(rgb);
            writeAttribute(colorNode, "colorR", rgb[0]);
            writeAttribute(colorNode, "colorG", rgb[1]);
            writeAttribute(colorNode, "colorB", rgb[2]);
        }

        //写如属性值
        writeAttribute(_node, "NonribbedPlatePropertyRef", getPhyscisPropertyObjectNameById(data->getSkinPropID()));
        writeAttribute(_node, "base_angle", data->getBaseAngle());
        writeAttribute(_node, "SpacingStandardDeviationFractionX", data->getDri1RibInfo()->getSpacingDevFraction());
        writeAttribute(_node, "SpacingStandardDeviationFractionY", data->getDri2RibInfo()->getSpacingDevFraction());
        //writeAttribute(_node, "material", getMaterialObjectNameById(data->getMaterialID()));
        //写加筋信息
        writeRibInfo();
        return true;
    }

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::readRibInfo(double r1, double r2)
    {
        auto ribSetNode = _node->first_node("RibSet");

        if (!ribSetNode)// 判断Fluid节点是否存在
        {
            return false;
        }

        bool b = true;
        //转换类型为梁
        Acoustics::FITKPhyscisPropertyRibbed* ribbed = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_dataObj);
        //记录当前是第几次读取加筋信息 第1次就是r1、第2次就是r2、其他数就是不正确的
        int index = 1;
        Acoustics::FITKPhyscisPropertyRibInfo* ribInfoData{};
        IO:: VAOneXMLAdaptorPhysicalPropertyRibInfo* adaptor{};
        // 循环处理每个RibSet节点数据
        while (ribSetNode)
        {
            if(index == 1)
            {
                ribInfoData = ribbed->getDri1RibInfo();
                ribInfoData->setSpacingDevFraction(r1);
                index++;
            }
            else if(index == 2)
            {
                ribInfoData = ribbed->getDri2RibInfo();
                ribInfoData->setSpacingDevFraction(r2);
                index++;
            }
            else
            {
                return true;
            }

            if(!ribInfoData)//正常情况下是不用判空的，在关联类里面自动new
            {
                return true;
            }

            if(!adaptor)
            {
                adaptor  = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorPhysicalPropertyRibInfo>("VAOneXML", ribInfoData);

            }

            if(!adaptor)
            {
                //读写器创建异常
                consoleMessage(3,"create VAOneXMLAdaptorPhysicalPropertyRibbed Error");
                return false;
            }

            adaptor->setNode(ribSetNode);
            adaptor->setDataObject(ribInfoData);
            b &= adaptor->adaptR();
            ribSetNode = ribSetNode->next_sibling("RibSet");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorPhysicalPropertyRibbed::writeRibInfo()
    {
        //转换类型
        Acoustics::FITKPhyscisPropertyRibbed* data = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_dataObj);//上一个函数已经判空
        Acoustics::FITKPhyscisPropertyRibInfo* ribInfoData{};
        bool b = true;
        IO:: VAOneXMLAdaptorPhysicalPropertyRibInfo* adaptor{};

        for(int i = 1; i < 3 ; i++)//循环两次是因为只有左右加筋信息
        {
            //创建节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "RibSet");
            if(i == 1)
            {
                ribInfoData = data->getDri1RibInfo();
            }
            else if(i == 2)
            {
                ribInfoData = data->getDri2RibInfo();
            }
            else
            {
                return true;
            }

            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorPhysicalPropertyRibInfo>("VAOneXML", ribInfoData);
            }

            if(!adaptor)
            {
                //读写器创建异常
                consoleMessage(3,"create adaptor Error");
                return false;
            }

            adaptor->setNode(node);
            adaptor->setAxisNumber(i);
            adaptor->setDataObject(ribInfoData);
            b &= adaptor->adaptW();

        }

        delete adaptor;
        adaptor = nullptr;
        return true;
    }

    int VAOneXMLAdaptorPhysicalPropertyRibbed::getPhyscisPropertyObjectIdByName(QString name)
    {
        //获取全局数据管理器
        auto globalData = FITKAPP->getGlobalData();

        if(!globalData)
        {
            return -1;// 如果转换失败，材料名称无法填写
        }
        //获取管理器
        Acoustics::FITKAcousticsPhysics* physics = globalData->getPhysicsData<Acoustics::FITKAcousticsPhysics>();

        if (!physics)
        {
            return -1;  // 如果转换失败，材料名称无法填写
        }

        auto physicsPropDataManager = physics->getPhysicsPropManager();

        if(!physicsPropDataManager)
        {
            return -1;
        }

        //根据名称获取数据类
        auto uniformData = physicsPropDataManager->getDataByName(name);

        if(uniformData)
        {
            //不为空返回数据id
            return uniformData->getDataObjectID();
        }
        return -1;//其他情况返回-1
    }

    QString VAOneXMLAdaptorPhysicalPropertyRibbed::getPhyscisPropertyObjectNameById(int id)
    {
        //获取全局数据管理器
        auto globalData = FITKAPP->getGlobalData();

        if(!globalData)
        {
            return "";// 如果转换失败，材料名称无法填写
        }
        //获取管理器
        Acoustics::FITKAcousticsPhysics* physics = globalData->getPhysicsData<Acoustics::FITKAcousticsPhysics>();

        if (!physics)
        {
            return "";  // 如果转换失败，材料名称无法填写
        }

        auto physicsPropDataManager = physics->getPhysicsPropManager();

        if(!physicsPropDataManager)
        {
            return "";
        }

        //根据名称获取数据类
        auto uniformData = physicsPropDataManager->getDataByID(id);

        if(uniformData)
        {
            //不为空返回数据id
            return uniformData->getDataObjectName();
        }
        return "";//其他情况返回
    }
}

